package com.zzyl.nursing.service.impl;


import java.util.List;
import com.zzyl.common.utils.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.zzyl.common.core.domain.entity.SysUser;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.interceptor.MyMetaObjectHandler;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.NursingElder;
import com.zzyl.nursing.dto.AlertDataDto;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.mapper.NursingElderMapper;
import com.zzyl.nursing.service.INursingElderService;
import com.zzyl.system.mapper.SysUserMapper;
import com.zzyl.system.mapper.SysUserRoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.AlertDataMapper;
import com.zzyl.nursing.domain.AlertData;
import com.zzyl.nursing.service.IAlertDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.Arrays;


import static org.apache.commons.collections4.CollectionUtils.size;


/**
 * 报警数据Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-05-05
 */
@Service


@Slf4j

public class AlertDataServiceImpl extends ServiceImpl<AlertDataMapper,AlertData> implements IAlertDataService
{
    @Autowired
    private AlertDataMapper alertDataMapper;


    @Autowired
    private NursingElderMapper nursingElderMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;



    @Autowired
    private SysUserMapper sysUserMapper;


    /**
     * 查询报警数据
     * 
     * @param id 报警数据主键
     * @return 报警数据
     */
    @Override
    public AlertData selectAlertDataById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询报警数据列表
     * 
     * @param alertData 报警数据
     * @return 报警数据
     */
    @Override
    public List<AlertData> selectAlertDataList(AlertData alertData)
    {

        //1.获得当前登录人员
        Long userId = MyMetaObjectHandler.loadUserId();
        //2.在数据库中查找当前登录人员对应的报警数据进行返回
        Long count = lambdaQuery().eq(AlertData::getUserId, userId).count();

        //3.判断报警数据是否为空
        if(count == 0){
            //4.如果为空，则返回空集合
            return Collections.emptyList();
        }

        alertData.setUserId(userId);



        log.info("查询报警数据：{}",alertDataMapper.selectAlertDataList(alertData));
        return alertDataMapper.selectAlertDataList(alertData);

    }

    /**
     * 新增报警数据
     * 
     * @param alertData 报警数据
     * @return 结果
     */
    @Override
    public int insertAlertData(AlertData alertData)
    {
        return save(alertData)?1:0;
    }

    /**
     * 修改报警数据
     * 
     * @param alertData 报警数据
     * @return 结果
     */
    @Override
    public int updateAlertData(AlertData alertData)
    {
        return updateById(alertData)?1:0;
    }

    /**
     * 批量删除报警数据
     * 
     * @param ids 需要删除的报警数据主键
     * @return 结果
     */
    @Override
    public int deleteAlertDataByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除报警数据信息
     * 
     * @param id 报警数据主键
     * @return 结果
     */
    @Override
    public int deleteAlertDataById(Long id)
    {
        return removeById(id)?1:0;
    }


    /**
     * 处理设备报警数据
     * @param alertDataDto
     */
    @Override
    public void handleAlertData(AlertDataDto alertDataDto) {

        //登录用户：管理员->修改管理员本人的报警数据->依据管理员关联数据查找 同样与该报警进行关联的 维修工 或 护理员 列表->遍历列表进行修改
        //登录用户：护理员->修改护理员本人的报警数据->依据护理员关联数据查找 同样与该报警进行关联的 护理员->遍历列表进行修改（会重复修改一次登录用户数据）->依据登录用户查找 同样与该报警关联的 管理员->修改关联数据
        //登录用户：维修工->修改维修工本人的报警数据->依据维修工关联数据查找 同样与该报警进行关联的 护理员->遍历列表进行修改（会重复修改一次登录用户数据）->依据登录用户查找 同样与该报警关联的 管理员->修改关联数据
        //修改登录用户的报警数据 1.修改登录用户数据 2.判断设备类型，获得护理员或维修工列表 3.遍历列表进行修改 4.判断该用户是否是管理员，不是的话查找管理员，修改管理员数据

        //获取id
        Long id = alertDataDto.getId();

        //获取处理时间
        LocalDateTime processingTime = alertDataDto.getProcessingTime();
        log.info("处理时间：{}",processingTime);

        //获取处理结果
        String processingResult = alertDataDto.getProcessingResult();

        //获取该登录用户关联的报警数据
        AlertData alertData = selectAlertDataById(id);
        //获取报警时间
        Date createTime = alertData.getCreateTime();

        //获取报警设备iotId
        String iotId = alertData.getIotId();

        //获取设备物模型
        String functionId = alertData.getFunctionId();

        //获得当前登录人员id
        Long userId = MyMetaObjectHandler.loadUserId();

        //更新该登录人员对应的报警数据
        //赋值给processing_id
        alertData.setProcessorId(userId);
        //依据userid查询当前登录对象
        SysUser sysUser = sysUserMapper.selectUserById(userId);

        //获取登录人员姓名
        String userName = sysUser.getUserName();

        //将姓名赋值给processing_name
        alertData.setProcessorName(userName);

        //修改处理结果
        alertData.setProcessingResult(processingResult);

        //修改处理时间
        alertData.setProcessingTime(processingTime);

        //修该状态为已处理 1
        alertData.setStatus(1);
        //保存报警数据
        updateAlertData(alertData);

        //修改user_id对应的报警数据
        //获取护理人员集合
        List<Long> nursingList = new ArrayList<>();
        //判断设备类型 如果是随身设备 则access_location是老人id
        if(alertData.getLocationType() == 0){
            //access_location获取老人
            String accessLocation = alertData.getAccessLocation();
            //转为 Long
            Long elderlyId = Long.valueOf(accessLocation);
            //依据老人id查找老人对应的护理人员id集合
             nursingList = nursingElderMapper.selectNursingElderByElderId(elderlyId);
             //更新用户id对应的报警数据
            getAlertDataByUserId(nursingList,iotId, functionId, createTime,userName,processingTime,processingResult);

        }else {
            //如果是床位 则查找该床位对应的老人physical_location_type
            if (alertData.getPhysicalLocationType() == 2){
                //依据床位id获取老人 id
                //获取床位id
                Long bedId = Long.valueOf(alertData.getAccessLocation());
                Long elderlyId = elderMapper.selectElderByBedId(bedId);
                //依据老人id查找老人对应的护理人员id集合
                nursingList = nursingElderMapper.selectNursingElderByElderId(elderlyId);
                //更新用户id对应的报警数据
                getAlertDataByUserId(nursingList,iotId, functionId, createTime,userName,processingTime,processingResult);


            }
            //如果是房间 则查找维修工人
            if (alertData.getPhysicalLocationType() == 1){
                //查找角色为“行政”的用户id
                List<Long> userIdList = sysUserRoleMapper.selectIdsByRoleName("行政");
                //更新用户id对应的报警数据
                getAlertDataByUserId(userIdList,iotId, functionId, createTime,userName,processingTime,processingResult);

            }

        }

        //判断登录人员是否是管理员
        if (!SysUser.isAdmin(userId)){
            //创建List<Long>集合，里面只有一个元素，该元素为管理员id 1
            List<Long> adminList = new ArrayList<>();
            adminList.add(1L);

            getAlertDataByUserId(adminList,iotId, functionId, createTime,userName,processingTime,processingResult);

        }
    }

    private void getAlertDataByUserId(List<Long> UserIds, String iotId, String functionId, Date createTime,String userName,LocalDateTime processingTime,String processingResult) {

        UserIds.forEach(userId -> {
            //获取该user关联的报警数据
            AlertData alertData2 = alertDataMapper.selectAlertDataByuserNursingId(userId, iotId, functionId, createTime);

            if (alertData2 != null){
                alertData2.setProcessorId(userId);

                //将姓名赋值给processing_name
                alertData2.setProcessorName(userName);

                //修改处理结果
                alertData2.setProcessingResult(processingResult);

                //修改处理时间
                alertData2.setProcessingTime(processingTime);

                //修该状态为已处理 1
                alertData2.setStatus(1);
                //保存报警数据
                updateAlertData(alertData2);
            }


        });
    }
}
